package com.ipan.weixin;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang.StringUtils;

import com.ipan.weixin.util.WxClassLoaderUtils;
import com.ipan.weixin.util.WxStringUtils;

/**
 * 环境配置
 * 
 * @author iPan
 * @version 2013-12-26
 */
public class WxConfiguration {
	public static final String ACCOUNT_TYPE_SER = "server";
	public static final String ACCOUNT_TYPE_SUB = "subscibe";
	private static final String STATUS_CODE_NAME_BEGIN = "weixin.status.code.";
	private static final String STATUS_CODE_FILE = "weixin_status_code.properties";
	private static final String CONFIG_FILE = "weixin.properties";
	private static WxConfiguration INSTANCE = new WxConfiguration();
	private Map<Integer, String> statusContext = null;
	private String token;
	private String appid;
	private String appsecret;
	private String urlToken;
	private String urlSend;
	private String urlGroupsCreate;
	private String urlGroupsGet;
	private String urlGroupsGetid;
	private String urlGroupsUpdate;
	private String urlGroupsMembersUpdate;
	private String urlUserInfo;
	private String urlUserGet;
	private String urlMenuCreate;
	private String urlMenuGet;
	private String urlMenuDelete;
	private String urlQrcodeCreate;
	private String urlQrcodeShowqrcode;
	private String accountType = "";
	private String encode = "UTF-8";

	public WxConfiguration() {
		InputStream in = null;
		try {
			in = WxClassLoaderUtils.getResourceAsStream(CONFIG_FILE, WxConfiguration.class);
			if (in != null) {
				Properties pro = new Properties();
				pro.load(in);
				// 初始化
				this.token = pro.getProperty("weixin.token");
				this.appid = pro.getProperty("weixin.appid");
				this.appsecret = pro.getProperty("weixin.appsecret");
				this.urlToken = pro.getProperty("weixin.url.token");
				this.urlSend = pro.getProperty("weixin.url.send");
				this.urlGroupsCreate = pro.getProperty("weixin.url.groups.create");
				this.urlGroupsGet = pro.getProperty("weixin.url.groups.get");
				this.urlGroupsGetid = pro.getProperty("weixin.url.groups.getid");
				this.urlGroupsUpdate = pro.getProperty("weixin.url.groups.update");
				this.urlGroupsMembersUpdate = pro.getProperty("weixin.url.groups.members.update");
				this.urlUserInfo = pro.getProperty("weixin.url.user.info");
				this.urlUserGet = pro.getProperty("weixin.url.user.get");
				this.urlMenuCreate = pro.getProperty("weixin.url.menu.create");
				this.urlMenuGet = pro.getProperty("weixin.url.menu.get");
				this.urlMenuDelete = pro.getProperty("weixin.url.menu.delete");
				this.urlQrcodeCreate = pro.getProperty("weixin.url.qrcode.create");
				this.urlQrcodeShowqrcode = pro.getProperty("weixin.url.qrcode.showqrcode");
				this.accountType = pro.getProperty("weixin.account.type");
				this.encode = pro.getProperty("weixin.message.encode");
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}
	}

	public static WxConfiguration getInstance() {
		return INSTANCE;
	}

	public Map<Integer, String> getStatusContext() {
		return statusContext;
	}

	public void setStatusContext(Map<Integer, String> statusContext) {
		this.statusContext = statusContext;
	}

	public String getToken() {
		return token;
	}

	public void setToken(String token) {
		this.token = token;
	}

	public String getAppid() {
		return appid;
	}

	public void setAppid(String appid) {
		this.appid = appid;
	}

	public String getAppsecret() {
		return appsecret;
	}

	public void setAppsecret(String appsecret) {
		this.appsecret = appsecret;
	}

	public String getUrlSend() {
		return urlSend;
	}

	public void setUrlSend(String urlSend) {
		this.urlSend = urlSend;
	}

	public String getUrlGroupsCreate() {
		return urlGroupsCreate;
	}

	public void setUrlGroupsCreate(String urlGroupsCreate) {
		this.urlGroupsCreate = urlGroupsCreate;
	}

	public String getUrlGroupsGet() {
		return urlGroupsGet;
	}

	public void setUrlGroupsGet(String urlGroupsGet) {
		this.urlGroupsGet = urlGroupsGet;
	}

	public String getUrlGroupsGetid() {
		return urlGroupsGetid;
	}

	public void setUrlGroupsGetid(String urlGroupsGetid) {
		this.urlGroupsGetid = urlGroupsGetid;
	}

	public String getUrlGroupsUpdate() {
		return urlGroupsUpdate;
	}

	public void setUrlGroupsUpdate(String urlGroupsUpdate) {
		this.urlGroupsUpdate = urlGroupsUpdate;
	}

	public String getUrlGroupsMembersUpdate() {
		return urlGroupsMembersUpdate;
	}

	public void setUrlGroupsMembersUpdate(String urlGroupsMembersUpdate) {
		this.urlGroupsMembersUpdate = urlGroupsMembersUpdate;
	}

	public String getUrlUserInfo() {
		return urlUserInfo;
	}

	public void setUrlUserInfo(String urlUserInfo) {
		this.urlUserInfo = urlUserInfo;
	}

	public String getUrlUserGet() {
		return urlUserGet;
	}

	public void setUrlUserGet(String urlUserGet) {
		this.urlUserGet = urlUserGet;
	}

	public String getUrlMenuCreate() {
		return urlMenuCreate;
	}

	public void setUrlMenuCreate(String urlMenuCreate) {
		this.urlMenuCreate = urlMenuCreate;
	}

	public String getUrlMenuGet() {
		return urlMenuGet;
	}

	public void setUrlMenuGet(String urlMenuGet) {
		this.urlMenuGet = urlMenuGet;
	}

	public String getUrlMenuDelete() {
		return urlMenuDelete;
	}

	public void setUrlMenuDelete(String urlMenuDelete) {
		this.urlMenuDelete = urlMenuDelete;
	}

	public String getUrlQrcodeCreate() {
		return urlQrcodeCreate;
	}

	public void setUrlQrcodeCreate(String urlQrcodeCreate) {
		this.urlQrcodeCreate = urlQrcodeCreate;
	}

	public String getUrlQrcodeShowqrcode() {
		return urlQrcodeShowqrcode;
	}

	public void setUrlQrcodeShowqrcode(String urlQrcodeShowqrcode) {
		this.urlQrcodeShowqrcode = urlQrcodeShowqrcode;
	}

	/**
	 * 返回状态信息，为空时返回空字符串；
	 */
	public String getStatusValue(Integer key) {
		checkStatusCode();
		String value = statusContext.get(key);
		return (value != null) ? value : "";
	}

	public List<Integer> allStatusKeys() {
		checkStatusCode();
		return new ArrayList<Integer>(statusContext.keySet());
	}
	
	public String getEncode() {
		return (StringUtils.isNotBlank(encode)) ? encode : "UTF-8";
	}

	public void setEncode(String encode) {
		this.encode = encode;
	}
	
	public String getUrlToken() {
		return urlToken;
	}

	public void setUrlToken(String urlToken) {
		this.urlToken = urlToken;
	}
	
	public String getAccountType() {
		return accountType;
	}

	public void setAccountType(String accountType) {
		this.accountType = accountType;
	}
	
	public static boolean isServerAccount(String accountType) {
		return ACCOUNT_TYPE_SER.equalsIgnoreCase(accountType);
	}
	
	public static boolean isSubscibeAccount(String accountType) {
		return ACCOUNT_TYPE_SUB.equalsIgnoreCase(accountType);
	}

	public static String fillUrlParam(String url, Map<String, String> params) {
		if (StringUtils.isEmpty(url)) {
			return url;
		}
		String urlStr = url;
		for (int p1 = urlStr.indexOf("${"); p1 >= 0; p1 = urlStr.indexOf("${")) {
			int p2 = urlStr.indexOf("}");
			String expr = urlStr.substring(p1 + 2, p2);
			String value = (params.get(expr) != null) ? params.get(expr) : "";
			urlStr = urlStr.replaceFirst("\\$\\{[\\w\\s]+\\}", value);
		}
		
		return urlStr;
	}
	
	public static String fillUrlParam(String url, String[] params) {
		if (StringUtils.isEmpty(url)) {
			return url;
		}
		String urlStr = url;
		for (int p1 = urlStr.indexOf("${"), index = 0; p1 >= 0; p1 = urlStr.indexOf("${")) {
			urlStr = urlStr.replaceFirst("\\$\\{[\\w\\s]+\\}", params[index++]);
		}
		return urlStr;
	}

	private synchronized void checkStatusCode() {
		if (statusContext == null) {
			statusContext = new HashMap<Integer, String>();
			loadStatusCode();
		}
	}

	private void loadStatusCode() {
		InputStream in = null;
		try {
			in = WxClassLoaderUtils.getResourceAsStream(STATUS_CODE_FILE, WxConfiguration.class);
			if (in != null) {
				Properties pro = new Properties();
				pro.load(in);
				Enumeration<?> keys = pro.keys();
				while (keys.hasMoreElements()) {
					String key = (String) keys.nextElement();
					Integer code = Integer.valueOf(WxStringUtils.substringAfter(key, STATUS_CODE_NAME_BEGIN));
					statusContext.put(code, pro.getProperty(key));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
				}
			}
		}
	}

}
